Welcome back.
I'm going to introduce you to a programming pattern called caching.
We have some expensive or maybe unreliable operation.
We'll have a little function, it takes an input,
produces an output, but it might take a long time to run it.
Each time we run it, we're going to take the results and
we'll stick them into a cache.
And that cache is going to save our previous results.
You can think of it sort of like a squirrel's cache of nuts,
it's spelled C-A-C-H-E, pronounced cache.
And it just associates some inputs with outputs.
I'll call them keys and results.
And now, the next time I was going to ask this expensive operation to do
the very same operation that's been done before, I would first check and
see, hey, is this result already available to me in the cache?
If it is, just send back the same result I would have gotten if I had run that
expensive operation, but don't bother, just take the result from the cache.
Now, in our case, the expensive operation is request.get.
It's expensive because it takes a little bit of time to go out over the Internet,
to make a connection with another server.
It's also a little unreliable.
Sometimes you don't have a good Internet connection, sometimes the server
that you're connecting to doesn't respond in the way that it did yesterday.
In our text book there's some sites that have restrictions on cross site scripting,
and some days it works to connect to them some days it doesn't.
There's another problem that sometimes when
we request.get we're doing some debugging and we run our code a bunch of times.
And the site that we're talking to as a rate limit, it says you can only make 15
calls every 15 minutes and you've run this more than 15 times in the last 15 minutes.
So these are all reasons why it's going to be good idea to
save our results when we run a request.get, put them in a cache, and get
the results from the cache the next time rather than calling request.get again.
So we've implemented this caching pattern in a module, it's available only
in the textbook and it's called, as you might guess, Request with Caching.
So in the code window here, I've got an import statement,
import requests_with_caching.
And then requests.with.caching is available to us and
we are going to call the method get.
This get method in requests.with.caching is going to return exactly the same
result, a response object, just like if I were to call request.get.
But the way it works is that, it's going to first look in the cache and
see if it can find the result there.
If so, it'll give us the results from the cache.
If it can't find it in the cache, it calls the real request.get and
it returns that but it also saves the result in the cache so that the next time,
we'll get the result from the cache.
And there's one little twist is that I've actually got,
in this request.caching module, we've implemented two caches.
There's stuff that we provided as part of the textbook and
that goes into a permanent cache file.
And then there's a temporary cache.
We can sort of think us having two caches, the permanent cache, And
then there's a temporary cache and you can think of it as a second little database.
And that's stuff that's saved between code runs while you're on the current page, but
it disappears when you reload the page.
So when you call requests_with_caching.get,
it checks in both of the caches.
If it's found in either place, it returns that.
If it doesn't find it in either place, then it does call request.get.
And it saves the result in this temporary, page specific cache.
So let's see what happens when we run this code.
So we have a cache file, a permanent cache file called, datamusecache.text.
And our first call,
to requests_with_caching that
get asks for the datamuse API.
And it asks for words that rhyme with happy.
And then we can see the results.
The requests_with_caching,get tells us whether it found the result in the caches
or whether it didn't.
In this case, it didn't find in the cache, and so
it says it's adding it to the cache.
Then on line four, I've printed the first 100 characters.
And you can see the things that are rhyming
are snappy, and nappy, and so on.
On line six, I'm making exactly the same request.
I'm asking for the same word, for words that rhyme with happy again.
And this time we're told that it found it in the page specific cache.
Because it saved it from the first time that we made the call.
The last call that we make, we're asking for
different words, we're asking for words that rhyme with funny.
And we have a cached result in the permanent cache file for
words that rhyme with funny, so it found that in the permanent cache.
Now if I were to run this whole thing again,
now it's going to run where it already has the page specific cache.
And by the way, you can see the results of that page specific cache.
It's telling us it's stored in this data file called this page cache.text and
it's the things that rhyme with happy, like snappy, nappy, and scrappy.
If I run this again, instead of showing new here,
it's going to tell us that it found it in the cache, so let's do that.
Takes it a little while to run.
Some inefficiencies, but we're going to see that new adding to cache is going to
change because it's going to find it in the cache.
So now it says it found it in the page specific cache.
If I were to reload this whole page, which I'll do now,
I'm going to clear my markings, and I'm going to reload the page.
Now I've reloaded the page, and that got rid of the page specific cache.
When I run this again, The first time,
it's going to have to do a call to request.get and add it to the cache.
That's the requests_with_caching module that we've provided.
It's really easy to use.
Just import requests_with_caching and then you call requests_with_caching.get
the same way as you would call request.get.
And it just makes it so that when you make the same request multiple times,
the additional times that you make the same request you'll get data from
the cache.
See you next time.